package com.appsindy.common.json;

import java.io.PrintWriter;
import java.util.List;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.Result;
import com.opensymphony.xwork2.util.ValueStack;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.basic.DateConverter;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;

/*
 * The JSONResult is a custom result to serlialize an object to the JSON format.  This
 * result type can be used to provide Ajax clients with JSON responses.
 * 
 * This result is basically just to show two things.  First, the fundamentals of making
 * a custom result.  And second, how Ajax applications can be easily integrated with the 
 * framework.  
 * 
 * This result takes a single parameter, classAlias, which will be the JSON object name
 * under which the domain model object will be serialized.  As far as what gets serialized,
 * the JSON result will look for a property on the ValueStack called jsonModel.  This 
 * value could arrive on the ValueStack via a variety of methods.     
 */

public class JSONResult implements Result {
	
	public static final String DEFAULT_PARAM = "classAlias";
	private String classAlias;
	
	public String getClassAlias() {
		return classAlias;
	}
	public void setClassAlias(String classAlias) {
		this.classAlias = classAlias;
	}
	
	public void execute(ActionInvocation invocation) throws Exception {
		ServletActionContext.getResponse().setContentType("text/plain");
		ServletActionContext.getResponse().setCharacterEncoding("UTF-8");
		PrintWriter responseStream = ServletActionContext.getResponse().getWriter();
		
		/* Retrieve Objects to Serialize to JSON from ValueStack */
		ValueStack valueStack = invocation.getStack();
		Object jsonModel = valueStack.findValue("jsonModel");
		
		XStream xstream = new XStream(new JettisonMappedXmlDriver());
		// xstream.registerConverter(new DateConverter("ddMMYYYY", new
		// String[0]));
		xstream.setMode(XStream.NO_REFERENCES);
		/*
		 * If there's no parameter passed in, just write the objects under a
		 * default name.
		 */
		xstream.addDefaultImplementation(java.sql.Date.class, java.util.Date.class);
		
		xstream.registerConverter(new AppsindyDateConverter());
		//xstream.registerConverter(new DateConverter("dd/MM/yyyy", new String[0]));
		
		if(classAlias == null){
			classAlias = "object";
		}
		xstream.alias(classAlias, jsonModel.getClass());
		Class clazz = jsonModel.getClass();
		Class objectClazz = null;
		// clazz.cast()
		
		if("TableData".equals(clazz.getSimpleName())) {
			TableData tableData = (TableData) clazz.cast(jsonModel);
			List l = tableData.getRecords();
			// System.out.println(" ============================
			// l.get(0).getClass(); =============== " + l.get(0).getClass());
			if (l != null && !l.isEmpty()) {
				objectClazz = l.get(0).getClass();
			} else {
				objectClazz = l.getClass();
			}
			xstream.alias("detail", objectClazz);
		}
		
		/* Write to the response stream */
		System.out.println("[JSONResult] TableData = " + xstream.toXML(jsonModel));
		responseStream.println(xstream.toXML(jsonModel));
	}
}
